package com.itheima.d2_reflect;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
    目标：掌握获取类的成员方法，并对其进行操作。

    Class类中的方法
        Method[] getMethods()	获取类的全部成员方法（只能获取public修饰的）
        Method[] getDeclaredMethods()	获取类的全部成员方法（只要存在就能拿到）
        Method getMethod(String name, Class<?>... parameterTypes) 	获取类的某个成员方法（只能获取public修饰的）
        Method getDeclaredMethod(String name, Class<?>... parameterTypes)	获取类的某个成员方法（只要存在就能拿到）
    Method提供的方法
        public Object invoke(Object obj, Object... args)	触发某个对象的该方法执行。
        public void  setAccessible(boolean flag)	设置为true，表示禁止检查访问控制（暴力反射）
 */
public class Test4Method {
    @Test
    public void testGetMethods(){
        // 获取所有成员方法
        Class cat = Cat.class;

        final Method[] declaredMethods = cat.getDeclaredMethods();

        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
    }

    @Test
    public void testMethods2() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 1. 获取字节类对象
        Class cat = Cat.class;

        // 2. 得到构造器
        final Constructor declaredConstructor = cat.getDeclaredConstructor();
        final Object catObj = declaredConstructor.newInstance();

        // 3. 获取方法并调用
        final Method eat = cat.getDeclaredMethod("eat");
        eat.invoke(catObj);

        // 4. 获取私有方法并调用
        final Method eat2 = cat.getDeclaredMethod("eat", String.class);
        eat2.setAccessible(true);
        final Object result = eat2.invoke(catObj, "鱼丸");
        System.out.println("result -> " + result);

    }
}
